package dynomicTable

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"

	"project-info/src/handle/response"
	"project-info/src/lib"
	"project-info/src/model"
	"gorm.io/gorm"
)

type BindReq struct {
	UserIds       []uint64 `json:"userIds"`
	RoleIds       []uint64 `json:"roleIds"`
	TableConfigId uint64   `json:"tableConfigId"`
	DataId        uint64   `json:"dataId"`
}

type DynamicPrivilegeEntity struct {
	DataId        uint64 `json:"dataId"`
	TableConfigId uint64 `json:"tableConfigId"`
}

type DynamicPrivilegeRes struct {
	UserIds []uint   `json:"userIds"`
	RoleIds []uint64 `json:"roleIds"`
	DynamicPrivilegeEntity
}

// GetDynamicTableData 获取动态表格数据
func GetDynamicTableData(c *lib.GinContext) error {
	type DataRequest struct {
		Page       int    `json:"page"`
		Size       int    `json:"size"`
		Query      string `json:"query"`
		ConfigName string `json:"configName"`
	}

	var req DataRequest
	if err := c.Bind(&req); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	configName := req.ConfigName
	if configName == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}

	if req.Page <= 0 {
		req.Page = 1
	}
	if req.Size <= 0 {
		req.Size = 10
	}

	// 检查配置是否存在
	var config model.TableConfig
	if err := model.DB().Where("name = ?", configName).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 获取字段配置
	fields := []model.FormField(config.Fields)

	tableName := "dynamic_table_" + configName

	// 构建查询SQL
	selectFields := []string{"id", "create_time", "update_time"}
	for _, field := range fields {
		selectFields = append(selectFields, "`"+field.Name+"`")
	}

	countSql := fmt.Sprintf("SELECT COUNT(*) FROM `%s`", tableName)
	dataSql := fmt.Sprintf("SELECT %s FROM `%s`", strings.Join(selectFields, ","), tableName)

	// 添加搜索条件
	if req.Query != "" {
		whereClauses := []string{}
		for _, field := range fields {
			if field.Type == "text" || field.Type == "textarea" {
				whereClauses = append(whereClauses, fmt.Sprintf("`%s` LIKE '%%%s%%'", field.Name, req.Query))
			}
		}
		if len(whereClauses) > 0 {
			whereClause := " WHERE " + strings.Join(whereClauses, " OR ")
			countSql += whereClause
			dataSql += whereClause
		}
	}

	// 获取总数
	var total int64
	if err := model.DB().Raw(countSql).Scan(&total).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "查询总数失败")
	}

	// 分页查询
	offset := (req.Page - 1) * req.Size
	dataSql += fmt.Sprintf(" ORDER BY id DESC LIMIT %d OFFSET %d", req.Size, offset)

	rows, err := model.DB().Raw(dataSql).Rows()
	if err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "查询数据失败")
	}
	defer rows.Close()

	// 解析查询结果
	var dataList []map[string]interface{}
	for rows.Next() {
		columns, _ := rows.Columns()
		values := make([]interface{}, len(columns))
		valuePtrs := make([]interface{}, len(columns))
		for i := range values {
			valuePtrs[i] = &values[i]
		}

		if err := rows.Scan(valuePtrs...); err != nil {
			continue
		}

		row := make(map[string]interface{})
		for i, col := range columns {
			val := values[i]
			if val != nil {
				if b, ok := val.([]byte); ok {
					row[col] = string(b)
				} else {
					row[col] = val
				}
			} else {
				row[col] = nil
			}
		}
		dataList = append(dataList, row)
	}

	result := map[string]interface{}{
		"records": dataList,
		"total":   total,
		"page":    req.Page,
		"size":    req.Size,
	}

	return response.JsonOk(c, result, "获取成功")
}

// AddDynamicTableData 添加动态表格数据
func AddDynamicTableData(c *lib.GinContext) error {
	var data map[string]interface{}
	if err := c.Bind(&data); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	configName, ok := data["configName"]
	if !ok || configName == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}
	// 检查配置是否存在
	var config model.TableConfig
	if err := model.DB().Where("name = ?", configName).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 获取字段配置
	fields := []model.FormField(config.Fields)

	// 验证必填字段
	for _, field := range fields {
		if field.Required {
			if value, exists := data[field.Name]; !exists || value == nil || value == "" {
				return response.JsonFail(c, fmt.Sprintf("字段 %s 不能为空", field.Label))
			}
		}
	}

	// 构建插入SQL
	tableName := "dynamic_table_" + configName.(string)
	columns := []string{}
	placeholders := []string{}
	values := []interface{}{}

	for _, field := range fields {
		if value, exists := data[field.Name]; exists {
			columns = append(columns, "`"+field.Name+"`")
			placeholders = append(placeholders, "?")

			// 处理特殊字段类型
			if field.Type == "checkbox" {
				// 多选框值转换为JSON字符串
				if valueBytes, err := json.Marshal(value); err == nil {
					values = append(values, string(valueBytes))
				} else {
					values = append(values, value)
				}
			} else {
				values = append(values, value)
			}
		}
	}

	if len(columns) == 0 {
		return response.JsonFail(c, "没有有效的数据字段")
	}

	insertSql := fmt.Sprintf("INSERT INTO `%s` (%s) VALUES (%s)",
		tableName,
		strings.Join(columns, ","),
		strings.Join(placeholders, ","))

	result := model.DB().Exec(insertSql, values...)
	if result.Error != nil {
		c.Logger().Error(result.Error.Error())
		return response.JsonFail(c, "添加数据失败")
	}

	return response.JsonOk(c, map[string]interface{}{
		"id": result.RowsAffected,
	}, "添加成功")
}

// UpdateDynamicTableData 更新动态表格数据
func UpdateDynamicTableData(c *lib.GinContext) error {
	var data map[string]interface{}
	if err := c.Bind(&data); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	configName, ok := data["configName"]
	if !ok || configName == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}

	// 检查ID
	idValue, exists := data["id"]
	if !exists || idValue == nil {
		return response.JsonFail(c, "数据ID不能为空")
	}

	id, ok := idValue.(float64)
	if !ok {
		return response.JsonFail(c, "数据ID格式错误")
	}

	// 检查配置是否存在
	var config model.TableConfig
	if err := model.DB().Where("name = ?", configName).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 获取字段配置
	fields := []model.FormField(config.Fields)

	// 验证必填字段
	for _, field := range fields {
		if field.Required {
			if value, exists := data[field.Name]; !exists || value == nil || value == "" {
				return response.JsonFail(c, fmt.Sprintf("字段 %s 不能为空", field.Label))
			}
		}
	}

	// 构建更新SQL
	tableName := "dynamic_table_" + configName.(string)
	setClauses := []string{}
	values := []interface{}{}

	for _, field := range fields {
		if value, exists := data[field.Name]; exists {
			setClauses = append(setClauses, "`"+field.Name+"` = ?")

			// 处理特殊字段类型
			if field.Type == "checkbox" {
				// 多选框值转换为JSON字符串
				if valueBytes, err := json.Marshal(value); err == nil {
					values = append(values, string(valueBytes))
				} else {
					values = append(values, value)
				}
			} else {
				values = append(values, value)
			}
		}
	}

	if len(setClauses) == 0 {
		return response.JsonFail(c, "没有有效的更新字段")
	}

	values = append(values, uint(id))
	updateSql := fmt.Sprintf("UPDATE `%s` SET %s WHERE id = ?",
		tableName,
		strings.Join(setClauses, ","))

	result := model.DB().Exec(updateSql, values...)
	if result.Error != nil {
		c.Logger().Error(result.Error.Error())
		return response.JsonFail(c, "更新数据失败")
	}

	if result.RowsAffected == 0 {
		return response.JsonFail(c, "数据不存在或未发生变化")
	}

	return response.JsonOk(c, nil, "更新成功")
}

// DeleteDynamicTableData 删除动态表格数据
func DeleteDynamicTableData(c *lib.GinContext) error {
	var data map[string]interface{}
	if err := c.Bind(&data); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	configName, ok := data["configName"]
	if !ok || configName == "" {
		return response.JsonFail(c, "配置名称不能为空")
	}

	idValue, exists := data["id"]
	if !exists || idValue == nil {
		return response.JsonFail(c, "数据ID不能为空")
	}

	id, ok := idValue.(float64)
	if !ok {
		return response.JsonFail(c, "数据ID格式错误")
	}

	// 检查配置是否存在
	var config model.TableConfig
	if err := model.DB().Where("name = ?", configName).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	tableName := "dynamic_table_" + configName.(string)
	deleteSql := fmt.Sprintf("DELETE FROM `%s` WHERE id = ?", tableName)
	if err := model.DB().Transaction(func(tx *gorm.DB) error {
		result := tx.Exec(deleteSql, uint(id))
		if result.Error != nil {
			c.Logger().Error(result.Error.Error())
			return result.Error
		}

		if result.RowsAffected == 0 {
			return errors.New("数据不存在")
		}
		if config.DataPermission {
			// 同步删除权限部分
			if err := tx.Where("data_id = ? and table_config_id = ?", uint(id), config.Id).Delete(&model.DynamicPrivilegeUser{}).Error; err != nil {
				return err
			}

			if err := tx.Where("data_id = ? and table_config_id = ?", uint(id), config.Id).Delete(&model.DynamicPrivilegeRole{}).Error; err != nil {
				return err
			}
		}
		return nil
	}); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "删除数据失败")
	}
	return response.JsonOk(c, nil, "删除成功")
}

type Option struct {
	Label string `json:"label"`
	Value uint64 `json:"value"`
}

// GetDynamicFieldOptions 获取动态表格字段选项
func GetDynamicFieldOptions(c *lib.GinContext) error {
	configName := c.QueryParam("configName")
	fieldName := c.QueryParam("fieldName")

	if configName == "" || fieldName == "" {
		return response.JsonFail(c, "参数不能为空")
	}

	// 检查配置是否存在
	var config model.TableConfig
	if err := model.DB().Where("name = ?", configName).First(&config).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "配置不存在")
	}

	// 获取字段配置
	fields := []model.FormField(config.Fields)

	// 查找指定字段
	var targetField *model.FormField
	for _, field := range fields {
		if field.Name == fieldName {
			targetField = &field
			break
		}
	}

	if targetField == nil {
		return response.JsonFail(c, "字段不存在")
	}

	// 从动态表格中获取选项
	var options []Option
	if err := model.DB().Table("dynamic_table_" + configName).Select(fieldName + " as label,id as value").Find(&options).Error; err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "获取选项失败")
	}

	return response.JsonOk(c, options, "获取成功")
}

// BindDynamicPrivilege 绑定动态权限
func BindDynamicPrivilege(c *lib.GinContext) error {
	// 1.解析参数
	var bindReq *BindReq
	if err := c.Bind(&bindReq); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}
	// 从bindReq中获取dynamicPrivilegeUser和dynamicPrivilegeRole
	var dynamicPrivilegeUser []*model.DynamicPrivilegeUser
	var dynamicPrivilegeRole []*model.DynamicPrivilegeRole
	for _, userId := range bindReq.UserIds {
		dynamicPrivilegeUser = append(dynamicPrivilegeUser, &model.DynamicPrivilegeUser{UserId: userId, DataId: bindReq.DataId, TableConfigId: bindReq.TableConfigId})
	}
	for _, roleId := range bindReq.RoleIds {
		dynamicPrivilegeRole = append(dynamicPrivilegeRole, &model.DynamicPrivilegeRole{DataId: bindReq.DataId, RoleId: roleId, TableConfigId: bindReq.TableConfigId})
	}

	err := model.DB().Transaction(func(tx *gorm.DB) error {
		// 2.删除数据
		if err := tx.Where("data_id = ? and table_config_id = ?", bindReq.DataId, bindReq.TableConfigId).Delete(&model.DynamicPrivilegeUser{}).Error; err != nil {
			return err
		}

		if err := tx.Where("data_id = ? and table_config_id = ?", bindReq.DataId, bindReq.TableConfigId).Delete(&model.DynamicPrivilegeRole{}).Error; err != nil {
			return err
		}

		// 3.保存数据
		if len(dynamicPrivilegeUser) > 0 {
			if err := tx.Create(&dynamicPrivilegeUser).Error; err != nil {
				return err
			}
		}
		if len(dynamicPrivilegeRole) > 0 {
			if err := tx.Create(&dynamicPrivilegeRole).Error; err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return response.JsonFail(c, "绑定失败")
	}
	return response.JsonOk(c, nil, "绑定成功")
}

// GetDynamicPrivilege 获取动态权限
func GetDynamicPrivilege(c *lib.GinContext) error {
	var req *DynamicPrivilegeEntity
	if err := c.Bind(&req); err != nil {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "参数解析错误")
	}

	var userIds []uint
	model.DB().Model(&model.DynamicPrivilegeUser{}).Where("data_id = ? and table_config_id = ?", req.DataId, req.TableConfigId).Pluck("user_id", &userIds)

	var roleIds []uint64
	model.DB().Model(&model.DynamicPrivilegeRole{}).Where("data_id = ? and table_config_id = ?", req.DataId, req.TableConfigId).Pluck("role_id", &roleIds)

	dynamicPrivilegeRes := &DynamicPrivilegeRes{
		UserIds: userIds,
		RoleIds: roleIds,
		DynamicPrivilegeEntity: DynamicPrivilegeEntity{
			DataId:        req.DataId,
			TableConfigId: req.TableConfigId,
		},
	}
	return response.JsonOk(c, dynamicPrivilegeRes, "查询成功")
}
